package com.guaoran.sso.intercept;

import com.guaoran.common.annotation.Anoymous;
import com.guaoran.common.constants.MallWebConstant;
import com.guaoran.common.utils.CookieUtil;
import com.guaoran.sso.controller.BaseController;
import com.guaoran.user.IUserCoreService;
import com.guaoran.user.dto.CheckAuthRequest;
import com.guaoran.user.dto.CheckAuthResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * Token 拦截器
 */
public class TokenIntercepter extends HandlerInterceptorAdapter {

    private final String ACCESS_TOKEN = "access_token";

    @Autowired
    IUserCoreService iUserCoreService;

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {
        //如果访问的不是方法则忽略
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Object bean = handlerMethod.getBean();

        //判断是否需要匿名访问
        if (isAnoymous(handlerMethod)) {
            return true;
        }
        //由于要存放用户的uid，需要继承 BaseController
        if (!(bean instanceof BaseController)) {
            throw new RuntimeException("must extend basecontroller");
        }
        //获得用户的token
        String token = CookieUtil.getCookieValue(request, ACCESS_TOKEN);
        //判断是否是ajax请求
        boolean isAjax = CookieUtil.isAjax(request);
        if (StringUtils.isEmpty(token)) {
            if (isAjax) {
                response.setContentType("text/html;charset=UTF-8");
                response.getWriter().write("{\"code\":\"-1\",\"msg\":\"error\"}");
                return false;
            }
            response.sendRedirect(MallWebConstant.MALL_SSO_ACCESS_URL);
            return false;
        }
        CheckAuthRequest checkAuthRequest = new CheckAuthRequest();
        checkAuthRequest.setToken(token);
        //校验token
        CheckAuthResponse checkAuthResponse = iUserCoreService.validToken(checkAuthRequest);
        //校验成功，保存UID，并进行方法的调用
        if ("000000".equals(checkAuthResponse.getCode())) {
            BaseController baseController = (BaseController) bean;
            baseController.setUid(checkAuthResponse.getUid());
            return super.preHandle(request, response, handler);
        }

        //如果token校验失败则返回登录或提示登录
        if (isAjax) {
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write("{\"code\":\"" + checkAuthResponse.getCode() + "\"" +
                    ",\"msg\":\"" + checkAuthResponse.getMsg() + "\"}");
            return false;
        }
        //登陆页面
        response.sendRedirect(MallWebConstant.MALL_SSO_ACCESS_URL);
        return false;
    }

    /**
     *  判断是否需要匿名访问
     * @param handlerMethod
     * @return
     */
    private boolean isAnoymous(HandlerMethod handlerMethod) {
        Object bean = handlerMethod.getBean();
        Class clazz = bean.getClass();
        if (clazz.getAnnotation(Anoymous.class) != null) {
            return true;
        }
        Method method = handlerMethod.getMethod();
        return method.getAnnotation(Anoymous.class) != null;
    }
}
